<?php


namespace app\api\controller\user;


use app\api\controller\Token;
use app\common\controller\Api;
use think\Db;
use think\Validate;

/**
 * 用户中心
 * */
class User extends Api
{
    protected $noNeedLogin = [ 'login', 'register', 'retrievePassword', 'retrieveAccount'];

    public function index()
    {
        $this->success('success', $this->auth);
    }

    /**
     * @title APP用户登录(POST)
     * @url api/user.user/login
     * @param integer mobile 手机号码
     * @param string password 登录密码
     * */
    public function login()
    {
        $mobile = $this->request->post('mobile', 0, 'intval') ?: $this->error('请输入手机号');
        $password = $this->request->post('password') ?: $this->error('请输入密码');

        if (!preg_match('/^1[345789]\d{9}$/', $mobile)) {
            $this->error('手机号码格式不正确');
        }
        if (!preg_match('/^(?![0-9]+$)(?![a-zA-Z]+$).{7,32}/', $password)) {
            $this->error('密码须同时包含数字和字母,长度7~32位');
        }
        $user = Db::name('user')->where('mobile', $mobile)->field('id,avatar,username,id_card,mobile,password,salt')->find();
        if (!$user) {
            $this->error('手机号码或密码不正确');
        } elseif (md5(md5($password) . $user['salt']) !== $user['password']) {
            $this->error('手机号码或密码不正确');
        } else {
            // 登录成功，返回用户信息和token
            $token = new Token();
            $this->success('登录成功', ['userInfo' => $user, 'tokenInfo' => $token->create($user['id'])]);
        }
    }

    /**
     * @title APP用户注册(POST)
     * @url api/user.user/register
     * @param string username 用户姓名
     * @param string id_card 身份证号
     * @param integer mobile 手机号
     * @param string password 密码
     * @param string password_confirm 确认密码
     * @param integer pay_password 支付密码
     * @param integer pay_password_confirm 确认支付密码
     * @param integer code 验证码
     * */
    public function register()
    {
        $username = $this->request->post('username');
        $id_card = $this->request->post('id_card');
        $mobile = $this->request->post('mobile', 0, 'intval');
        $password = $this->request->post('password');
        $password_confirm = $this->request->post('password_confirm');
        $pay_password = $this->request->post('pay_password');
        $pay_password_confirm = $this->request->post('pay_password_confirm');
        $code = $this->request->post('code', 0, 'intval') ?: $this->error('请输入短信验证码');
        $validate = new \app\api\validate\user\User();
        $params = [
            'username' => $username,
            'id_card' => $id_card,
            'mobile' => $mobile,
            'password' => $password,
            'password_confirm' => $password_confirm,
            'pay_password' => $pay_password,
            'pay_password_confirm' => $pay_password_confirm,
        ];
        // 验证数据格式是否合法
        if (!$validate->check($params)) {
            $this->error($validate->getError());
        }
        // 验证手机验证码是否正确或者是否在有效期范围内
        $code_verify = Db::name('sms')->where(['mobile' => $mobile, 'verification' => $code])->order('id', 'desc')->find();
        if (!$code_verify) {
            $this->error('验证码不正确');
        } elseif (time() > $code_verify['expiretime']) {
            $this->error('验证码已过期，请重新获取');
        }
        // 验证用户姓名和身份证号码是否已经注册
        $exit_check = Db::name('user')->where(['username' => $username, 'id_card' => $id_card])->whereOr('mobile', $mobile)->value('id');
        if ($exit_check) {
            $this->error('该用户身份证或者手机号码已被注册');
        }
        // 验证码使用过后设置验证码过期
        Db::name('sms')->where('id', $code_verify['id'])->update(['expiretime' => 0]);

        $password_salt = random_code(); // 登录密码的盐
        $pay_salt = random_code(); // 支付密码的盐
        // 创建用户
        $data = [
            'username' => $username,
            'avatar' => '', // 设置一个默认头像
            'id_card' => $id_card,
            'mobile' => $mobile,
            'password' => md5(md5($password) . $password_salt),
            'salt' => $password_salt,
            'pay_password' => md5(md5($pay_password) . $pay_salt),
            'pay_salt' => $pay_salt,
            'createtime' => time(),
        ];
        $res = Db::name('user')->insert($data);
        if ($res) {
            $this->success('注册成功，请前往登录');
        } else {
            $this->error();
        }
    }

    /**
     * @title APP用户找回登录密码(POST)
     * @url api/user.user/retrievePassword
     * @param string username 用户姓名
     * @param string id_card 身份证号
     * @param integer mobile 手机号
     * @param string password 密码
     * @param string password_confirm 确认密码
     * @param integer code 验证码
     * */
    public function retrievePassword()
    {
        $username = $this->request->post('username');
        $id_card = $this->request->post('id_card');
        $mobile = $this->request->post('mobile', 0, 'intval');
        $password = $this->request->post('password');
        $password_confirm = $this->request->post('password_confirm');
        $code = $this->request->post('code', 0, 'intval') ?: $this->error('请输入短信验证码');
        $validate = new \app\api\validate\user\User();
        $params = [
            'username' => $username,
            'id_card' => $id_card,
            'mobile' => $mobile,
            'password' => $password,
            'password_confirm' => $password_confirm,
        ];
        // 验证数据格式是否合法
        if (!$validate->check($params)) {
            $this->error($validate->getError());
        }
        // 验证手机验证码是否正确或者是否在有效期范围内
        $code_verify = Db::name('sms')->where(['mobile' => $mobile, 'verification' => $code])->order('id', 'desc')->find();
        if (!$code_verify) {
            $this->error('验证码不正确');
        } elseif (time() > $code_verify['expiretime']) {
            $this->error('验证码已过期，请重新获取');
        }
        // 验证码使用过后设置验证码过期
        Db::name('sms')->where('id', $code_verify['id'])->update(['expiretime' => 0]);
        // 查找该用户是否存在
        $user_id = Db::name('user')->where(['username' => $username, 'id_card' => $id_card, 'mobile' => $mobile])->value('id');
        if (!$user_id) {
            $this->error('您还未成为我们的会员，请先进行注册');
        }
        // 更新用户信息
        $password_salt = random_code(); // 登录密码的盐
        // 更新用户密码
        $data = [
            'password' => md5(md5($password) . $password_salt),
            'salt' => $password_salt,
        ];
        $res = Db::name('user')->where('id', $user_id)->update($data);
        if ($res) {
            $this->success('密码修改成功，请前往登录');
        }
    }

    /**
     * @title APP用户找回登录密码(POST)
     * @url api/user.user/retrieveAccount
     * @param string username 用户姓名
     * @param string id_card 身份证号
     * @return array mobile 手机号码
     * */
    public function retrieveAccount()
    {
        $username = $this->request->post('username', '', 'strip_tags') ?: $this->error('请输入用户姓名');
        $id_card = $this->request->post('id_card', '', 'strip_tags') ?: $this->error('请输入身份证号码');
        // 查找用户信息
        $mobile = Db::name('user')->where(['username' => $username, 'id_card' => $id_card])->value('mobile');
        if (!$mobile) {
            $this->error('您还未成为我们的会员，或者输入的信息有误');
        } else {
            $mobile = '*******' . substr($mobile, -4);
            $this->success('账号找回成功', ['mobile' => $mobile]);
        }
    }

    /**
     * @title APP用户找回支付密码(POST)
     * @url api/user.user/retrievePayPassword
     * @param string username 用户姓名
     * @param string id_card 身份证号
     * @param integer mobile 手机号
     * @param string password 密码
     * @param string password_confirm 确认密码
     * @param integer code 验证码
     * */
    public function retrievePayPassword()
    {
        $username = $this->request->post('username');
        $id_card = $this->request->post('id_card');
        $mobile = $this->request->post('mobile', 0, 'intval');
        $pay_password = $this->request->post('pay_password');
        $pay_password_confirm = $this->request->post('pay_password_confirm');
        $code = $this->request->post('code', 0, 'intval') ?: $this->error('请输入短信验证码');
        $validate = new \app\api\validate\user\User();
        $params = [
            'username' => $username,
            'id_card' => $id_card,
            'mobile' => $mobile,
            'pay_password' => $pay_password,
            'pay_password_confirm' => $pay_password_confirm,
        ];
        // 验证数据格式是否合法
        if (!$validate->check($params)) {
            $this->error($validate->getError());
        }
        // 验证手机验证码是否正确或者是否在有效期范围内
        $code_verify = Db::name('sms')->where(['mobile' => $mobile, 'verification' => $code])->order('id', 'desc')->find();
        if (!$code_verify) {
            $this->error('验证码不正确');
        } elseif (time() > $code_verify['expiretime']) {
            $this->error('验证码已过期，请重新获取');
        }
        // 验证码使用过后设置验证码过期
        Db::name('sms')->where('id', $code_verify['id'])->update(['expiretime' => 0]);
        $user_id = Db::name('user')->where(['username' => $username, 'id_card' => $id_card, 'mobile' => $mobile])->value('id');
        if (!$user_id) {
            $this->error('您提交的身份信息不正确，请重新验证身份');
        }
        // 更新用户信息
        $pay_salt = random_code(); // 登录密码的盐
        $data = [
            'pay_password' => md5(md5($pay_password) . $pay_salt),
            'pay_salt' => $pay_salt,
        ];
        $res = Db::name('user')->where('id', $user_id)->update($data);
        if ($res) {
            $this->success('您的支付密码修改成功，请妥善保存');
        }
    }

    /**
     * @title APP用户更换绑定的手机号(POST)
     * @url api/user.user/changeMobile
     * @param string username 用户姓名
     * @param string id_card 身份证号
     * @param integer old_mobile 手机号
     * @param integer code 验证码
     * @param integer new_mobile 验证码
     * */
    public function changeMobile()
    {
        $username = $this->request->post('username', '', 'strip_tags') ?: $this->error('请输入用户姓名');
        $id_card = $this->request->post('id_card', '', 'strip_tags') ?: $this->error('请输入身份证号');
        $old_mobile = $this->request->post('old_mobile', 0, 'intval') ?: $this->error('请输入旧手机号');
        $code = $this->request->post('code', 0, 'intval') ?: $this->error('请输入短信验证码');
        $new_mobile = $this->request->post('new_mobile', 0, 'intval') ?: $this->error('请输入新手机号');
        if (!Validate::regex($old_mobile, "/^1\d{10}$/")) {
            $this->error('旧手机号码格式不正确');
        }
        if (!Validate::regex($old_mobile, "/^1\d{10}$/")) {
            $this->error('新手机号码格式不正确');
        }
        // 验证手机验证码是否正确或者是否在有效期范围内
        $code_verify = Db::name('sms')->where(['mobile' => $old_mobile, 'verification' => $code])->order('id', 'desc')->find();
        if (!$code_verify) {
            $this->error('验证码不正确');
        } elseif (time() > $code_verify['expiretime']) {
            $this->error('验证码已过期，请重新获取');
        }
        // 验证码使用过后设置验证码过期
        Db::name('sms')->where('id', $code_verify['id'])->update(['expiretime' => 0]);
        $user_id = Db::name('user')->where(['username' => $username, 'id_card' => $id_card, 'mobile' => $old_mobile])->value('id');
        if (!$user_id) {
            $this->error('您提交的身份信息不正确，请重新验证身份');
        }
        // 身份验证通过后，修改用户的手机号码
        $res = Db::name('user')->where(['id' => $this->auth['id']])->where(['username' => $username, 'id_card' => $id_card, 'mobile' => $old_mobile])->update(['mobile' => $new_mobile]);
        if ($res) {
            $this->success('更换手机号码成功');
        } else {
            $this->error('未知错误');
        }
    }

    /**
     * @title APP用户个人信息(GET)
     * @url api/user.user/profile
     * @return array data 用户信息
     * */
    public function profile()
    {
        $user_id = $this->auth['id'];
        $userInfo = Db::name('user')->where('id', $user_id)->field('id,username,id_card,avatar,mobile,invited')->find();
        if ($userInfo) {
            $data = [
                'avatar' => $userInfo['avatar'],
                'username' => starReplace($userInfo['username']),
                'invited' => $userInfo['invited']
            ];
            // 15位和18位身份证处理
            if (mb_strlen($userInfo['id_card'], 'utf-8') == 15) {
                $data['id_card'] = mb_substr($userInfo['id_card'], 0, 4, 'utf-8') . '********' . mb_substr($userInfo['id_card'], 12, 15, 'utf-8');
            } else {
                $data['id_card'] = mb_substr($userInfo['id_card'], 0, 6, 'utf-8') . '********' . mb_substr($userInfo['id_card'], 14, 18, 'utf-8');
            }
        }
        $this->success('获取成功', $data);
    }

    /**
     * @title APP用户退出登录(GET)
     * @url api/user.user/logout
     * */
    public function logout()
    {
        // 删除token
        $res = Db::name('user_token')->where('user_id', $this->auth['id'])->delete();
        if ($res) {
            $this->success('退出成功');
        }
    }

    /**
     * @title 用户绑定银行卡(POST)
     * @url api/user.user/binkBank
     * @param integer account 银行卡账号
     * @param integer bank_id 所属银行ID
     * */
    public function binkBank()
    {
        $account = $this->request->post('account', 0, 'intval') ?: $this->error('请输入银行卡号');
        $bank_id = $this->request->post('bank_id', 0, 'intval') ?: $this->error('请选择所属的银行');
        $bankInfo = Db::name('bank_category')->where('id', $bank_id)->value('id');
        if (!$bankInfo) {
            $this->error('所属银行不存在');
        }
        $data = [
            'user_id' => $this->auth['id'],
            'account' => $account,
            'bank_id' => $bank_id
        ];
        $exit_bank = Db::name('user_bank')->where('user_id', $this->auth['id'])->value('id');
        // 如果用户已经绑定过银行卡，则更新银行卡信息，否则重新插入一条记录
        if (!$exit_bank) {
            $res = Db::name('user_bank')->where('user_id', $this->auth['id'])->insert($data);
        } else {
            $res = Db::name('user_bank')->where('id', $exit_bank)->update($data);
        }
        $this->success('银行卡绑定成功');
    }

    /**
     * @title 地址管理(POST)
     * @url api/user.user/setAddress
     * @param integer provice_id 省份ID
     * @param integer city_id 城市ID
     * @param integer county_id 区/县ID
     * @param string address 详细地址
     * @param integer post_code 邮政编码
     * */
    public function setAddress()
    {
        $this->request->filter('trim,strip_tags,htmlspecialchars');
        $province_id = $this->request->post('province_id', 0, 'intval') ?: $this->error('请所在选择省份');
        $city_id = $this->request->post('city_id', 0, 'intval') ?: $this->error('请所在选择城市');
        $county_id = $this->request->post('county_id', 0, 'intval') ?: $this->error('请所在选择区/县');
        $address = $this->request->post('address', '', '') ?: $this->error('请输入详细地址');
        $post_code = $this->request->post('post_code', 0, 'intval') ?: $this->error('请输入邮政编码');
        $data = [
            'user_id' => $this->auth['id'],
            'province_id' => $province_id,
            'city_id' => $city_id,
            'county_id' => $county_id,
            'address' => $address,
            'post_code' => $post_code,
        ];
        $res = Db::name('user_address')->insert($data);
        if ($res) {
            $this->success('设置成功');
        }
    }

    /**
     * @title 获取个人推广二维码(GET)
     * @url api/common/getQrcode
     * */
    public function getQrcode()
    {
        $params = [
            'user_id' => $this->auth['id']
        ];
        Vendor('phpqrcode.phpqrcode');
        $object = new \QRcode();
        $errorCorrectionLevel = 'L';    //容错级别
        $matrixPointSize = 5;            //生成图片大小
        //打开缓冲区
        ob_start();
        //生成二维码图片
        $returnData = $object->png(json_encode($params), false, $errorCorrectionLevel, $matrixPointSize, 2);
        //这里就是把生成的图片流从缓冲区保存到内存对象上，使用base64_encode变成编码字符串，通过json返回给页面。
        $imageString = base64_encode(ob_get_contents());
        //关闭缓冲区
        ob_end_clean();
        $base64 = "data:image/png;base64," . $imageString;

        $data = [
            'username' => $this->auth['username'],
            'invited' => $this->auth['invited']
        ];
        // 15位和18位身份证处理
        if (mb_strlen($this->auth['id_card'], 'utf-8') == 15) {
            $data['id_card'] = mb_substr($this->auth['id_card'], 0, 4, 'utf-8') . '********' . mb_substr($this->auth['id_card'], 12, 15, 'utf-8');
        } else {
            $data['id_card'] = mb_substr($this->auth['id_card'], 0, 6, 'utf-8') . '********' . mb_substr($this->auth['id_card'], 14, 18, 'utf-8');
        }
        base64_image_content($base64, ROOT_PATH . '/public/uploads', 'user-' . $this->auth['id'] . '-qrcode');
        $data['qrcode'] = config('config.domain') . 'uploads/' . date('Ymd', time()) . '/user-' . $this->auth['id'] . '-qrcode.png';
        $this->success('二维码生成成功', $data);

    }

    /**
     * @title 会员签到(GET)
     * @url api/user.user/sign
     * */
    public function sign()
    {
        $signTime = date('Y-m-d');
        $data = [
            'user_id' => $this->auth['id'],
            'signtime' => $signTime
        ];
        $exit_sign = Db::name('user_sign')->where($data)->value('id');
        if ($exit_sign) {
            $this->error('您今天已经签到过了');
        } else {
            $res = Db::name('user_sign')->insert($data);
            if ($res) {
                // 增加累计消费笔数
                Db::name('user')->where('id', $this->auth['id'])->setInc('count_consume', 1);
                $this->success('签到成功，累计消费笔数+1');
            }
        }
    }

    /**
     * @title 默认支付设置页面(GET)
     * @url api/user.user/payType
     * */
    public function payType()
    {
       $type = Db::name('pay_type')->order('id','asc')->select();
       $userBank = Db::name('user_bank')
           ->alias('a')
           ->join('bank_category b','a.bank_id = b.id')
           ->where('user_id',$this->auth['id'])
           ->field('a.*,b.name as bankName,b.icon')
           ->find();
        foreach ($type as &$row) {
            // 设置选中状态
            $row['check'] = false;
            if ($this->auth['pay_type']==$row['id']) {
                $row['check'] = true;
            }
            $row['icon'] = config('config.domain').$row['icon'];
            // 未绑定银行卡
            if ($row['name']=='银行卡支付' && !$userBank) {
                $row['name'] = '银行卡支付（未绑定银行卡）';
            } elseif($row['name']=='银行卡支付' && $userBank) {
                $row['icon'] = config('config.domain').$userBank['icon'];
                $row['name'] = $userBank['bankName'].'('.substr($userBank['account'],-4).')';
            }
        }
        $this->success('获取成功',$type);
    }
    /**
     * @title 设置默认支付方式(POST)
     * @url api/user.user/setPayType
     * @param integer type_id
     * */
    public function setPayType()
    {
        $type_id = $this->request->post('type_id',0,'intval')?:$this->error('请求参数错误');
        $res = Db::name('user')->where(['id'=>$this->auth['id']])->update(['pay_type'=>$type_id]);
        if ($res) {
            $this->success('设置成功');
        }else{
            $this->error('已设置');
        }
    }

}